package com.lemon.stock.viewmodel

import android.content.Context
import android.net.Uri
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.lemon.java.storage.FileUtil
import com.lemon.stock.app.StockApplication
import com.lemon.stock.compose.mine.ImportState
import com.lemon.stock.dao.BatchDao
import com.lemon.stock.dao.BonusDao
import com.lemon.stock.dao.StockDao
import com.lemon.stock.dao.TradeDao
import com.lemon.stock.entity.Batch
import com.lemon.stock.entity.Stock
import com.lemon.stock.net.SinaStock
import com.lemon.stock.util.*
import kotlinx.coroutines.launch
import java.io.BufferedReader
import java.io.FileInputStream
import java.io.InputStreamReader
import java.text.SimpleDateFormat
import java.util.*

class ImportViewModel: ViewModel() {
    private val _process = MutableLiveData(ImportState.ready)

    val process: LiveData<Int> = _process
    var message: String = ""

    fun reload(){
        _process.postValue(ImportState.again)
    }

    fun changeProcess(newProcess: Int){
        _process.postValue(newProcess)
    }
    fun importFromLocal(context: Context, uri: Uri){
        _process.postValue(ImportState.importing)
        viewModelScope.launch {
            //try{
                val filename = FileUtil.getPath(context, uri)
                val charset = FileUtil.getCharset(filename)

                val fis = FileInputStream(filename) //文件字节流
                val isr = InputStreamReader(fis, charset) //字节流和字符流的桥梁，可以指定指定字符格式

                val br2 = BufferedReader(isr)
                var result = br2.readText()
                /*
                var str = br2.readLine()
                var result = ""
                while (str != null) {
                    result += "$str"
                    str = br2.readLine()
                }
                 */
                handleRecordData(result)
            /*
            }catch (ex: Exception){
                Log.w("Error", ex.stackTrace.toString())
                _process.postValue(ImportState.fail)
                throw ex
            }

             */

        }

    }

    fun importFromRemote(){

    }

    fun handleRecordData(data: String){
        val records = data.split("\n".toRegex())//.toTypedArray()
        if(records.isNotEmpty()){
            var fields = mutableMapOf("id" to -1, "amount" to -1, "date" to -1, "price" to -1, "money" to -1,
                "commission" to -1, "transfer" to -1, "tax" to -1, "occur" to -1, "business" to -1)

            val stockDao = StockApplication.getDataRoom().stockDao()
            var liStock = stockDao.allStocks()
            var stocks = mutableMapOf<String, Stock>()
            for(stock in liStock){
                stocks[stock.stockId] = stock
            }
            var first = true
            var unStocks = mutableListOf<String>()

            for (record in  records){
                if(record.isNotBlank()){
                    val cols = record.split(",")//.toTypedArray()
                    if(first){
                        for((i, v) in cols.withIndex()){
                            when(v){
                                "发生日期" -> { fields["date"] = i}
                                "业务名称" -> { fields["business"] = i }
                                "证券代码" -> { fields["id"] = i }
                                "成交价格" -> { fields["price"] = i }
                                "成交数量" -> { fields["amount"] = i }
                                "成交金额" -> { fields["money"] = i }
                                "手续费" -> { fields["commission"] = i }
                                "印花税" -> { fields["tax"] = i }
                                "过户费" -> { fields["transfer"] = i }
                                "发生金额" -> { fields["occur"] = i }
                            }
                        }
                        first = false
                    }else{
                        var stockId = cols[fields["id"]!!]
                        if(stockId.isBlank()){
                            continue
                        }
                        if(stockId.length<6){
                            stockId = String.format("%06d", stockId.toInt())
                        }
                        if(!stocks.containsKey(stockId)){
                            val stockQuery = sysStockExchange(stockId)
                            if(stockQuery.isNotBlank() && stockQuery.length==8 && !unStocks.contains(stockQuery)){
                                unStocks.add(sysStockExchange(stockId))
                            }

                        }
                    }
                }
            }

            if(unStocks.isNotEmpty()){
                SinaStock.send(unStocks) {
                    liStock = stockDao.allStocks()
                    stocks = mutableMapOf<String, Stock>()
                    for(stock in liStock){
                        stocks[stock.stockId] = stock
                    }
                    intoRoom(stocks, records, fields)
                }
            }else{
                intoRoom(stocks, records, fields)
            }
        }
    }

    fun intoRoom(stocks: Map<String, Stock>, records: List<String>, fields: Map<String, Int>){
        val stockDao = StockApplication.getDataRoom().stockDao()
        val tradeDao = StockApplication.getDataRoom().tradeDao()
        val bonusDao = StockApplication.getDataRoom().bonusDao()
        val batchDao = StockApplication.getDataRoom().batchDao()

        val simpleDateFormat = SimpleDateFormat("yyyyMMdd", Locale.getDefault())

        var first = true
        for (record in  records) {
            if (record.isNotBlank()) {
                val cols = record.split(",")//.toTypedArray()
                if(first){
                    batchDao.clear()
                    tradeDao.clear()
                    bonusDao.clear()

                    for(stock in stocks.values){
                        sysStockZero(stock)
                        stock.status = 8
                        stock.totalProfit = 0f
                        stock.investIndex = 0
                        stockDao.update(stock)
                    }
                    first = false
                }else{
                    Log.w("lemon", "发生日期"+ cols[fields["date"]!!] + "业务名称"+ cols[fields["business"]!!] + "证券代码"+ cols[fields["id"]!!] + "成交价格"+ cols[fields["price"]!!]  )
                    var stockId = cols[fields["id"]!!]
                    if(stockId.isBlank()){
                        continue
                    }
                    var business = cols[fields["business"]!!]
                    var occur = cols[fields["occur"]!!].toFloat()

                    if(stockId.length<6){
                        stockId = String.format("%06d", stockId.toInt())
                    }
                    var stock = stocks[stockId]
                    if(business.indexOf("买入")>=0){
                        business = "买入"
                    }else if(business.indexOf("卖出")>=0){
                        business = "卖出"
                    }else if(business.indexOf("股息入帐")>=0 && occur>=0){
                        business = "分红"
                    }else if(business.indexOf("红股入帐")>=0 && occur>=0){
                        business = "分股"
                    }else if(business.indexOf("红利税")>=0 || (business.indexOf("股息入帐")>=0 && occur<0)){
                        business = "红利税"
                    }else{
                        business = "不处理"
                    }
                    //val date = cols[fields["date"]!!].toFloat()
                    val price = cols[fields["price"]!!].toFloat()
                    var amount = cols[fields["amount"]!!].toFloat().toInt()
                    val money = cols[fields["money"]!!].toFloat()
                    val commission = cols[fields["commission"]!!].toFloat()
                    val tax = cols[fields["tax"]!!].toFloat()
                    val transfer = cols[fields["transfer"]!!].toFloat()
                    //val dateTime = "2020-12-13 17:54:00"

                    val date = simpleDateFormat.parse(cols[fields["date"]!!])
                    val stamp  = date.time
                    if(amount < 0){
                        amount = -amount
                    }
                    if(cols[fields["date"]!!] == "20120309"){
                        val aaa = "100"
                    }
                    when(business){
                        "买入" ->buyStock(tradeDao, stock!!, price, amount, stamp, commission, transfer)
                        "卖出" ->sellStock(tradeDao, batchDao, stockDao, stock!!,
                            price, amount, stamp, commission, transfer, tax)
                        "分红" ->bonusStock(tradeDao, bonusDao, stock!!, money/amount, 0f, stamp, amount)
                        "分股" ->bonusStock(tradeDao, bonusDao, stock!!, 0f, amount.toFloat()/stock.holdStock, stamp, 0)
                        "红利税" ->taxStock(batchDao, stock!!, occur)
                    }
                }
            }
        }

        for(stock in stocks.values){
            sysStockGather(stock)
            stockDao.update(stock)
        }
        message += "成功导入${records.size}条数据"
        _process.postValue(ImportState.success)

    }

    private fun buyStock(tradeDao: TradeDao, stock: Stock, price: Float, amount: Int, date: Long, commission: Float, transfer: Float){
        var trade = sysStockBuy(stock,price, amount, date, commission, transfer)
        stock.holdStock += amount
        stock.investMoney += amount*price
        if(stock.maxAmount< stock.holdStock){
            stock.maxAmount = stock.holdStock
        }
        if(stock.maxInvest< stock.investMoney){
            stock.maxInvest = stock.investMoney
        }

        tradeDao.insert(trade)
        //sysStockGather(stock)
    }
    private fun sellStock(tradeDao: TradeDao, batchDao: BatchDao, stockDao: StockDao, stock: Stock,
                          price: Float, amount: Int, date: Long, commission: Float, transfer: Float, tax: Float){
        val pairs = sysStockSell(tradeDao, stock, price, amount, date, commission, transfer, tax)
        var split = pairs.first
        var saveTrade = pairs.second

        var batch: Batch? = null

        for(trade in saveTrade){
            tradeDao.update(trade)
        }
        if(split !=null){
            tradeDao.insert(split)
        }
        sysStockGather(stock)

        if(stock.holdStock == 0){
            batch = sysStockBatch(stock, date)
            if(batch !=null){
                batchDao.insert(batch)
                tradeDao.endBatch(stock.stockId, stock.investIndex)
            }
        }

        stockDao.update(stock)
    }

    private fun bonusStock(tradeDao: TradeDao, bonusDao: BonusDao, stock: Stock, money: Float, amount: Float, date: Long, holder: Int){
        if(stock.stockId == "002156"){
            val aaa = "100"
        }
        if(stock.holdStock<=0){
            return
        }
        val triple = sysStockBonus(tradeDao, stock, date, money, amount, holder)
        var bonus = triple.first
        var liTrade = triple.second
        var bonusTrade = triple.third

        bonusDao.insert(bonus)

        for(trade in liTrade){
            trade.bonusId = bonus.id
            tradeDao.update(trade)
        }
        if(bonusTrade !=null){
            tradeDao.insert(bonusTrade)
        }
        //stockDao.update(stock)
    }

    private fun taxStock(batchDao: BatchDao, stock: Stock, money: Float){
        if(stock.status == 6){
            stock.bonusTax += -money
        }else{
            var batch = batchDao.getEntity(stock.stockId,  stock.investIndex)
            stock.bonusTax += -money
            batchDao.update(batch)
        }
    }

}